home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / ICR / vr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-01  |  21.4 KB  |  1,027 lines  |  [TEXT/CWIE]

  1. /*
  2. ** Raster Virtual Kernel
  3. */
  4.  
  5. #ifdef MPW
  6. #pragma segment ICR
  7. #endif
  8.  
  9. #define MASTERDEF
  10.  
  11.  
  12.  
  13. #include "vr.h"
  14. #include "vr.proto.h"
  15. #include "vrrgmac.proto.h"
  16.  
  17. /*    defines for raster states and variables */
  18.  
  19. /*    states    */
  20. #define    DONE        0        /* we've been called */
  21. #define    ESCFOUND    1        /* found escape */
  22. #define    WANTCMD        2        /* want a command char */
  23. #define    WANTDEL        3        /* want that first delimiter */
  24. #define    IARG        4        /* looking for integer arg */
  25. #define    SARG        5        /* looking for string arg */
  26. #define    CARG        6        /* looking for count arg */
  27. #define    DATA        7        /* all args parsed, found ^ */
  28.  
  29. /*    commands */
  30. #define ESC        0x1b            /* start of a sequence */
  31. #define    ESCCMD    ' '                /* escape to next level of commands */
  32. #define    DELIM    ';'                /* argument delimiter */
  33. #define    CMDTRM    '^'                /* terminator, but also prefix w/ ESC */
  34. #define    WINCMD    'W'                /* create a window */
  35. #define    DESCMD    'D'                /* destroy a window */
  36. #define    MAPCMD    'M'                /* change color map entries */
  37. #define    RLECMD    'R'                /* run-length encoded data */
  38. #define    PIXCMD    'P'                /* standard pixel data */
  39. #define IMPCMD  'I'             /* IMCOMP compressed data */
  40. #define    FILCMD    'F'                /* save to file command */
  41. #define    CLKCMD    'C'                /* click the slide camera */
  42. #define    SAVCMD    'S'                /* save a color map to a file */
  43.  
  44. /*    command parameter types*/
  45. #define    MAXARGS    7                /* maximum args to a command */
  46. #define INT        1                /* integer argument */
  47. #define    STRING    2                /* string (character) argument */
  48. #define    COUNT    3                /* data count argument */
  49. #define LINEMAX 1024            /* longest width for window */
  50.  
  51. /*
  52. ** flag values
  53. */
  54.  
  55. #define FL_NORMAL    1        /* command needs no data */
  56. #define    FL_DATA        2        /* command takes data */
  57.  
  58. /*
  59. ** structure of command table
  60. */
  61.  
  62. struct cmd {
  63.     char    c_name;
  64.     short    c_flags;
  65.     short    (*c_func)(union arg av[], char *);
  66.     short    c_args[MAXARGS];
  67. };
  68.  
  69. static    struct cmd cmdtab[] = {
  70.     WINCMD, FL_NORMAL, VRwindow, {INT, INT, INT, INT, INT, STRING, 0},
  71.     DESCMD, FL_NORMAL, VRdestroy, {STRING, 0, 0, 0, 0, 0, 0},
  72.     MAPCMD, FL_DATA, VRmap, {INT, INT, COUNT, STRING, 0, 0, 0},
  73.     FILCMD, FL_NORMAL, VRfile, {INT, INT, INT, INT, INT, STRING, STRING},
  74.     PIXCMD, FL_DATA, VRpixel, {INT, INT, INT, COUNT, STRING, 0, 0},
  75.     RLECMD, FL_DATA, VRrle, {INT, INT, INT, COUNT, STRING, 0, 0},
  76.     IMPCMD, FL_DATA, VRimp, {INT, INT, INT, COUNT, STRING, 0, 0},
  77.     CLKCMD, FL_NORMAL, VRclick, {STRING, 0, 0, 0, 0, 0, 0},
  78.     SAVCMD, FL_NORMAL, VRmsave, {STRING, STRING, 0, 0, 0, 0, 0}
  79. };
  80.  
  81. #define NCMDS    (sizeof(cmdtab) / sizeof(struct cmd))
  82.  
  83. /*
  84. ** global vars
  85. */
  86.  
  87. static short            VRstate = DONE;        /* current state */
  88. static short            VRcmdnum = -1;        /* current command */
  89. static short            VRargcount = 0;        /* number of args for command */
  90. static short            VRdatalen = 0;        /* length of expected data */
  91. static short            VRbufpos = 0;        /* current pointer in tempdata */
  92. static union arg    VRargs[MAXARGS];    /* argument vector */
  93. static char            VRtempdata[256];    /* temporary storage while parsing */
  94. static char         *VRspace;            /* storage for incoming data */
  95. static char         *VRsp2;                /* storage for pixel expansion */
  96. static char            *VRptr;                /* pointer for data buffer */
  97. static char            *VRptr2;            /* copy of above */
  98.  
  99. /***********************************************************************/
  100. /* decode0 and decode1
  101. *  start and continue the decoding.
  102. *
  103. *  Returns real characters, 0 if in the middle of an escape sequence.
  104. */
  105.  
  106. #define FRSKIP 0
  107. #define FRIN 1
  108. #define FRSPECIAL 2
  109. #define FROVER 3
  110. #define FRDONE 4
  111.  
  112. void    ICRunload(void)    {}
  113.  
  114. static short VRnextargstate(short ac, short c);
  115.  
  116. /*
  117. ** VRinit    -- initialize the VR system
  118. **
  119. ** Arguments:
  120. **
  121. **    None.
  122. **
  123. ** Returns:
  124. **
  125. **    short        -- status, 1 == succsessful, 0 == failed
  126. */
  127.  
  128. short    VRinit( void)
  129. {
  130.     VRhead.w_next = NULL;
  131.     VRsp2 = (char *)myNewPtr(4*LINEMAX+10);
  132.     VRspace = (char *)myNewPtr(LINEMAX+10);
  133.  
  134.     if (VRspace)
  135.         return 1;
  136.     else
  137.         return 0;
  138. }
  139.  
  140. /*
  141. ** VRwrite -- parse a string of VR commands
  142. ** 
  143. ** Arguments:
  144. **
  145. **    char *b;    -- buffer pointer
  146. **    short    len;    -- buffer length
  147. **
  148. ** Returns:
  149. **
  150. **    short            -- Number of characters processed.  0 tells
  151. **                -- the upper level to switch out of raster mode;
  152. **                -- usually on error, but also at completion of
  153. **                -- command processing.
  154. **
  155. */
  156.  
  157. short    VRwrite( char *b, short len)
  158. {
  159.     short        count = 0;
  160.     char        *p = b;
  161.     char        c;
  162.     short        i;
  163.  
  164.     /*    loop 'til no more chars */
  165.  
  166.     while (count < len) {
  167.         c = *p;
  168.  
  169.         switch (VRstate) {
  170.             case DONE:
  171.                 if (c == ESC)
  172.                     VRstate = ESCFOUND;
  173.                 else
  174.                     return count;
  175.                 break;
  176.  
  177.             case ESCFOUND:
  178.                 if (c == CMDTRM)
  179.                     VRstate = WANTCMD;
  180.                 else {
  181.                     VRstate = DONE;
  182.                     return count;
  183.                 }
  184.                 break;
  185.  
  186.             /*    looking for a valid command char */
  187.             case WANTCMD:
  188.                 for (i = 0; i < NCMDS; i++) {
  189.                     if (cmdtab[i].c_name == c)
  190.                         break;
  191.                     }
  192.  
  193.                 VRcmdnum = i;
  194.  
  195.                 if (VRcmdnum == NCMDS) {
  196.                     VRstate = DONE;
  197.                     return 0;
  198.                     }
  199.  
  200.                 /*    set up for this command */
  201.                 VRargcount = 0;
  202.                 VRbufpos = 0;
  203.  
  204.                 VRstate = WANTDEL;
  205.                 break;
  206.  
  207.             /*    look for that first ; */
  208.             case WANTDEL:
  209.                 if (c == DELIM)
  210.                     VRstate = VRnextargstate(VRargcount, VRcmdnum);
  211.                 else
  212.                     VRstate = DONE;
  213.                 break;
  214.  
  215.             /*    looking for an integer arg */
  216.             case IARG:
  217.                 switch (c) {
  218.  
  219.                     /*    we've found the end of the argument, so
  220.                         try to put into the vector for later use */
  221.                     case DELIM:
  222.                     case CMDTRM:
  223.                         VRtempdata[VRbufpos] = '\0';
  224.  
  225.                         /*    copy into argument union */
  226.                         (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
  227.                         VRbufpos = 0;
  228.  
  229.                         VRargcount++;
  230.                         if (c == DELIM)
  231.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  232.                         else
  233.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  234.                                 VRstate = DATA;
  235.                             else {    /*    run the command */
  236.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  237.                                 VRstate = DONE;
  238.                             }
  239.                         break;
  240.  
  241.                     /*    copy over characters for later */
  242.                     default:
  243.                         VRtempdata[VRbufpos++] = c;
  244.                 }
  245.                 break;
  246.  
  247.             /*    looking for string arg */
  248.             case SARG:
  249.                 switch (c) {
  250.                     /*    put string into argument vector */
  251.                     case DELIM:
  252.                     case CMDTRM:
  253.                         
  254.                         VRtempdata[VRbufpos] = '\0';
  255. /*
  256.                         VRargs[VRargcount].a_ptr = myNewPtr((unsigned)VRbufpos+1);
  257.                         
  258.                         if (VRargs[VRargcount].a_ptr == (char *)0L) {
  259.                             VRstate = DONE;
  260.                             break;
  261.                         }
  262. */
  263.  
  264.                         (void)strcpy(VRargs[VRargcount].a_ptr, VRtempdata);
  265.                         VRbufpos = 0;
  266.                         VRargcount++;
  267.                         if (c == DELIM)
  268.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  269.                         else
  270.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  271.                                 VRstate = DATA;
  272.                             else {    /*    run the command */
  273.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  274.                                 VRstate = DONE;
  275.                             }
  276.                         break;
  277.  
  278.                     /*    save string for later */
  279.                     default:
  280.                         VRtempdata[VRbufpos++] = c;
  281.                 }
  282.                 break;
  283.  
  284.             /*    looking for a count argument */
  285.             case CARG:
  286.                 switch (c) {
  287.                     /*    we've found the end of the argument, so
  288.                         try to put into the vector for later use */
  289.                     case DELIM:
  290.                     case CMDTRM:
  291.                         VRtempdata[VRbufpos] = '\0';
  292.  
  293.                         /*    copy into argument union */
  294.                         (void)sscanf(VRtempdata,"%d",&VRdatalen);
  295.                         (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num);
  296.  
  297.                         if (VRdatalen > LINEMAX)
  298.                             VRdatalen = LINEMAX;
  299.                         VRargcount++;
  300.                         VRbufpos = 0;
  301.  
  302.                         if (c == DELIM)
  303.                             VRstate = VRnextargstate(VRargcount, VRcmdnum);
  304.                         else
  305.                             if (cmdtab[VRcmdnum].c_flags & FL_DATA)
  306.                                 VRstate = DATA;
  307.                             else {    /*    run the command */
  308.                                 (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L);
  309.                                 VRstate = DONE;
  310.                             }
  311.  
  312.                         /*    allocate storage for data */
  313.                         VRptr = VRspace;
  314.  
  315.                         if (VRptr == (char *)0L) {
  316.                             VRstate = DONE;
  317.                             return 0;
  318.                             }
  319.     
  320.                         VRptr2 = VRptr;
  321.                         decode0();            /* reset decoder */
  322.                         break;
  323.  
  324.                     /*    copy over characters for later */
  325.                     default:
  326.                         VRtempdata[VRbufpos++] = c;
  327.                 }
  328.                 break;
  329.  
  330.             /*    retrieve a line of data */
  331.             case DATA:
  332.                 /*    store bytes until done */
  333.                 if (0 <= (i = decode1(c))) {
  334.                     *VRptr2++ = i;
  335.                     --VRdatalen;
  336.                     }
  337.  
  338.                 if (!VRdatalen) {    /*    we've got all of the data */
  339.                     (*cmdtab[VRcmdnum].c_func)(VRargs, VRptr);
  340.                     VRstate = DONE;
  341.                     }
  342.                 break;
  343.  
  344.         } /* end switch(VRstate)*/
  345.  
  346.         p++;
  347.         count++;
  348.     } /* end while loop */
  349.  
  350.     return count;
  351. }
  352.  
  353. /*
  354. ** VRnextargstate -- return the next state based on where we're
  355. **                  -- at already.
  356. **
  357. ** Arguments:
  358. **
  359. ** short ac         -- current argument count
  360. ** short state       -- current state
  361. ** short c          -- current command
  362. **
  363. ** Returns:
  364. **
  365. ** short             -- next state to move to
  366. **
  367. */
  368.  
  369. static short VRnextargstate(short ac, short c)
  370. {
  371.  
  372.     switch (cmdtab[c].c_args[ac]) {
  373.         case INT:
  374.             return IARG;
  375.         case STRING:
  376.             return SARG;
  377.         case COUNT:
  378.             return CARG;
  379.         case 0:
  380.             return DATA;
  381.  
  382.         /*    in case of error*/
  383.         default:
  384.             return DONE;
  385.     }
  386. }
  387.  
  388. /*
  389. ** VRwindow -- create a new raster window
  390. **
  391. ** Arguments:
  392. **
  393. **    union arg av[];    -- the argument vector
  394. **
  395. **    short        av[0, 1];     -- upper left;
  396. **    short        av[2, 3];     -- width, height
  397. **    short        av[4];         -- window hardware display number
  398. **    char    *av[5];       -- title
  399. **
  400. ** Returns:
  401. **
  402. **    None.  No provision has been made for error returns in any of
  403. **    these routines because I don't know what to do if an error
  404. **    occurs.  Perhaps a better man than I can figure out how to 
  405. **    deal with this.
  406. **    N.B -- these functions are declared as short, in the event
  407. **    that an error return is added.
  408. */
  409.  
  410. short    VRwindow(union arg av[], char *unused)
  411. {
  412.     UNUSED_ARG(unused)
  413.     VRW    *w = VRhead.w_next;
  414.     short    ret;
  415.     
  416.     /*    search list, and if needed, myNewPtr some space for a new window thing */
  417.  
  418.     while (w) {
  419.         if (!strcmp(w->w_name,av[5].a_ptr)
  420.             && w->w_width == av[2].a_num 
  421.             && w->w_height == av[3].a_num)        /* don't re-allocate win */
  422.             return(1);
  423.         if (!strcmp(w->w_name,av[5].a_ptr))        /* duplicate, different size */
  424.             w->w_used = 1;
  425.         w = w->w_next;
  426.     }
  427.  
  428.     w = (VRW *)myNewPtr(sizeof(VRW));                /* new element for list */
  429.     if (!w)
  430.         return(-1);
  431.         
  432.     w->w_next = VRhead.w_next;                    /* set next equal to current head */
  433.     VRhead.w_next = w;                            /* set head of list equal to me */
  434.     
  435.     /*
  436.     ** fill in the new window area
  437.     */
  438.  
  439.     w->w_left = av[0].a_num;
  440.     w->w_top = av[1].a_num;
  441.     w->w_width = av[2].a_num;
  442.     w->w_height = av[3].a_num;
  443.     w->w_display = av[4].a_num;
  444.     w->w_used = 0;
  445.     strncpy(w->w_name,av[5].a_ptr,100);
  446.  
  447.     if (w->w_width > LINEMAX)            /* have to be SOME limits */
  448.         w->w_width = LINEMAX;
  449.  
  450.     if (0 <= (ret = MacRGnewwindow( w->w_name, w->w_left, w->w_top,
  451.                     w->w_left+w->w_width, w->w_top+w->w_height )))
  452.         MacRGsetwindow( ret);
  453.  
  454.     w->w_rr.wn = ret;
  455.  
  456.     return(ret);
  457. }
  458.  
  459. /*
  460. ** VRdestroy -- destroy a window by name
  461. **
  462. ** Arguments:
  463. **
  464. **   union arg av[]; -- the argument vector
  465. **
  466. **   char *av[0] -- the name of the window
  467. **
  468. ** Returns:
  469. **
  470. **   None.
  471. **
  472. */
  473.  
  474. short    VRdestroy(union arg av[], char *unused)
  475. {
  476.     UNUSED_ARG(unused)
  477.     VRW        *w,*ow;
  478.  
  479.     ow = &VRhead;
  480.     w = ow->w_next;
  481.  
  482.     while (w) {
  483.         if (!strcmp(w->w_name, av[0].a_ptr) ) {
  484.             MacRGremove( w->w_rr.wn);
  485.             ow->w_next = w->w_next;
  486.             DisposPtr((char *)w);
  487.         }
  488.         else
  489.             ow = ow->w_next;
  490.  
  491.         w = ow->w_next;
  492.     }
  493.  
  494.     return 0;
  495. }
  496.  
  497. void    VRdestroybyName(char *name)
  498. {
  499.     union arg blah;
  500.     
  501.     strncpy(blah.a_ptr, name, 100);
  502.     VRdestroy(&blah, NULL);
  503. }
  504.  
  505. /*
  506. ** VRmap -- take a color map command and set the palette
  507. **
  508. ** Arguments:
  509. **
  510. **   union arg av[]; -- the argument vector
  511. **
  512. **   short     av[0, 1];  -- start & length of map segment
  513. **     short    av[2];     -- count of data needed (info only)
  514. **     char    *av[3];    -- window name
  515. **   char    *data;     -- pointer to the data  
  516. **
  517. ** Returns:
  518. **
  519. **   None.
  520. **
  521. */
  522.  
  523. short    VRmap(union arg av[], char *data)
  524. {
  525.     VRW            *w;
  526.  
  527.     w = VRlookup(av[3].a_ptr);
  528.  
  529.     if (!w)
  530.         return 0;
  531.  
  532.     return MacRGmap(av[0].a_num, av[1].a_num, data);
  533. }
  534.  
  535. /*
  536. ** VRpixel -- display a line of pixel data
  537. ** 
  538. ** Arugments:
  539. **
  540. **    union arg av[]; -- the argument vector
  541. **
  542. **    short        av[0];  -- x coordinate
  543. **    short         av[1];  -- y coordinate
  544. **  short     av[2];  -- pixel expansion factor
  545. **    short         av[3];  -- length of data
  546. **    char    *av[4]; -- window name
  547. **    char    *data;  -- pointer to data
  548. **
  549. ** Returns:
  550. **
  551. **    None.
  552. **
  553. */
  554.  
  555. short    VRpixel(union arg av[], char *data)
  556. {
  557.     VRW        *w;
  558.     short    i,lim;
  559.     char    *p,*q;
  560.  
  561.     /*    find the right window */
  562.     w = VRlookup(av[4].a_ptr);
  563.  
  564.     if (w == (VRW *)0L)
  565.         return 0;
  566.  
  567.     lim = av[3].a_num*av[2].a_num;        /* total number of expanded pixels */
  568.     if (lim > w->w_width)
  569.         lim = w->w_width;
  570.  
  571.     if (av[2].a_num > 1) {
  572.         p = data;
  573.         q = VRsp2;
  574.         for (i=0; i < lim; i++) {
  575.             *q++ = *p;
  576.             if (!((i+1) % av[2].a_num))
  577.                 p++;
  578.         }
  579.         for (i=0; i<av[2].a_num; i++)
  580.             MacRGraster( VRsp2, av[0].a_num, av[1].a_num+i,
  581.                              av[0].a_num+lim, av[1].a_num+i,lim);
  582.  
  583.     }
  584.     else
  585.         return     MacRGraster( data, av[0].a_num, av[1].a_num,
  586.                     av[0].a_num+av[3].a_num, av[1].a_num,lim);
  587.  
  588.     return 0;
  589. }
  590.  
  591. /*
  592. ** VRimp -- display a line of IMPCOMP encoded data
  593. **   One line of IMPCOMP data gives 4 lines output.
  594. ** 
  595. ** Arugments:
  596. **
  597. **    union arg av[]; -- the argument vector
  598. **
  599. **    short        av[0];  -- x coordinate
  600. **    short         av[1];  -- y coordinate
  601. **  short     av[2];  -- pixel expansion
  602. **    short         av[3];  -- length of data
  603. **    char    *av[4]; -- window name
  604. **    char    *data;  -- pointer to data
  605. **
  606. ** Returns:
  607. **
  608. **    None.
  609. **
  610. */
  611.  
  612. short    VRimp(union arg av[], char *data)
  613. {
  614.     VRW        *w;
  615.     short    i,lim,j;
  616.     char    *p,*q;
  617.  
  618.     /*    find the right window */
  619.     w = VRlookup(av[4].a_ptr);
  620.  
  621.     if (w == (VRW *)0L)
  622.         return 0;
  623.  
  624.     unimcomp((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width);   /* BYU LSC - decompress it */
  625.     /* gives four lines in the VRsp2 buffer, now pixel expand */
  626.  
  627.     i = av[3].a_num;
  628.  
  629.     lim = i*av[2].a_num;        /* total number of expanded pixels on a line*/
  630.     if (lim > w->w_width)
  631.         lim = w->w_width;
  632.     if (i > w->w_width)
  633.         i = w->w_width;
  634.  
  635.     p = VRsp2;                                /* from this buffer */
  636.     for (j=0; j<4; j++) {
  637.         if (av[2].a_num > 1) {
  638.             q = VRspace;                    /* to here */
  639.             for (i=0; i < lim; i++) {
  640.                 *q++ = *p;
  641.                 if (!((i+1) % av[2].a_num))
  642.                     p++;
  643.             }
  644.             p++;
  645.             for (i=0; i<av[2].a_num; i++)
  646.                 MacRGraster(VRspace, av[0].a_num, av[1].a_num+i+j*av[2].a_num,
  647.                     av[0].a_num + av[3].a_num,    av[1].a_num+i+j*av[2].a_num, lim );
  648.  
  649.         }
  650.         else {
  651.             MacRGraster(p, av[0].a_num,        av[1].a_num+j,
  652.                     av[0].a_num + av[3].a_num, av[1].a_num+j, i);
  653.             p += av[3].a_num;            /* increment to next line */
  654.         }
  655.  
  656.     }
  657.  
  658.     return 0;
  659. }
  660.  
  661. /************************************************************************/
  662. /*  Function    : unimcomp                        */
  663. /*  Purpose    : 'Decompresses' the compressed image            */
  664. /*  Parameter    :                            */
  665. /*    xdim       - x dimensions of image                */
  666. /*    lines      - number of lines of compressed image                  */
  667. /*    in, out    - Input buffer and output buffer. Size of input buffer */
  668. /*           is xdim*lines. Size of output buffer is 4 times      */
  669. /*           that. It 'restores' images into seq-type files       */
  670. /*  Returns      : none                            */
  671. /*  Called by   : External routines                    */
  672. /*  Calls       : none                            */
  673. /************************************************************************/
  674.  
  675. void unimcomp(unsigned char in[], unsigned char out[], short xdim, short xmax)
  676. {
  677.   short                bitmap, temp, lines=1;
  678.   register short     i, j, k, x;
  679.   unsigned char        hi_color, lo_color;
  680.  
  681.     if (xmax < xdim)        /* don't go over */
  682.         xdim = xmax;
  683.  
  684.   /* go over the compressed image */
  685.     for (x=0; x<xdim; x=x+4)
  686.     {
  687.       k = x;
  688.       hi_color = in[k+2]; 
  689.       lo_color = in[k+3];
  690.  
  691.       bitmap = (in[k] << 8) | in[k+1];
  692.  
  693.       /* store in out buffer */
  694.       for (i=0; i<4; i++)
  695.       {
  696.         temp = bitmap >> (3 - i)*4;
  697.         for (j=x; j<(x+4); j++)
  698.         {
  699.        if ((temp & 8) == 8)
  700.         out[i*xdim+j] = hi_color;
  701.       else
  702.         out[i*xdim+j] = lo_color;
  703.       temp = temp << 1;
  704.     }
  705.       }
  706.     } /* end of for x */
  707. } /* end of unimcomp */
  708.  
  709. /*  unrleit - Decompress run length encoding. */
  710. short    unrleit(unsigned char *buf, unsigned char *bufto, short inlen, short outlen)
  711. {
  712.     register short            cnt;
  713.     register unsigned char    *p,*q;
  714.     unsigned char            *endp,*endq;
  715.     
  716.     p = buf;
  717.     endp = buf + inlen;
  718.     q = bufto;
  719.     endq = bufto + outlen;
  720.     while (p < endp && q < endq) {    /* go 'til p or q hits end */
  721.         cnt = *p++;                    /* count field */
  722.         if (!(cnt & 128)) {            /* is set of uniques */
  723.             while (cnt-- && q < endq)
  724.                 *q++ = *p++;        /* copy unmodified */
  725.             }
  726.         else {
  727.             cnt &= 127;                /* strip high bit */
  728.             while (cnt-- && q < endq)
  729.                 *q++ = *p;            /* copy same character */
  730.             p++;                    /* skip that character */
  731.         }
  732.     } /* while */
  733.  
  734.     return((short)(q-bufto));
  735. }
  736.  
  737. /***************************************************************************/
  738. /*
  739. ** VRrle -- display a line of run-length encoded data
  740. ** 
  741. ** Arugments:
  742. **
  743. **    union arg av[]; -- the argument vector
  744. **
  745. **    short        av[0];  -- x coordinate
  746. **    short         av[1];  -- y coordinate
  747. **  short     av[2];  -- pixel expansion
  748. **    short         av[3];  -- length of data
  749. **    char    *av[4]; -- window name
  750. **    char    *data;  -- pointer to data
  751. **
  752. ** Returns:
  753. **
  754. **    None.
  755. **
  756. */
  757. short    VRrle(union arg av[], char *data)
  758. {
  759.     VRW     *w;
  760.     short    i,lim;
  761.     char    *p,*q;
  762.  
  763.     /*    find the right window */
  764.  
  765.     w = VRlookup(av[4].a_ptr);
  766.  
  767.     if (w == (VRW *)0L)
  768.         return 0;
  769.  
  770.     i = unrleit((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width);   /* BYU LSC - decompress it */
  771.  
  772.  
  773.     lim = i*av[2].a_num;                /* total number of expanded pixels */
  774.     if (lim > w->w_width)
  775.         lim = w->w_width;
  776.  
  777.     if (av[2].a_num > 1) {
  778.         p = VRsp2;                        /* from this buffer */
  779.         q = VRspace;                    /* to here */
  780.         for (i=0; i < lim; i++) {
  781.             *q++ = *p;
  782.             if (!((i+1) % av[2].a_num))
  783.                 p++;
  784.         }
  785.         for (i=0; i<av[2].a_num; i++)
  786.             MacRGraster( VRspace, av[0].a_num, av[1].a_num+i,
  787.                              av[0].a_num+lim, av[1].a_num+i,lim);
  788.  
  789.     }
  790.     else
  791.         return     MacRGraster( VRsp2, av[0].a_num, av[1].a_num,
  792.                     av[0].a_num+i, av[1].a_num,i);
  793.  
  794.     return 0;
  795.  
  796. }
  797.  
  798. /*
  799. ** VRfile    -- cause the named window to be dumped to a file
  800. **
  801. ** Arguments:
  802. **
  803. **    union arg av[];        -- the argument vector
  804. **
  805. **    short        av[0];        -- start x coordinate
  806. **    short        av[1];        -- start y coordinate
  807. **    short        av[2];        -- width of region to dump
  808. **    short        av[3];        -- height of region to dump
  809. **    short        av[4];        -- format of file -- machine dependent
  810. **    char    *av[5];        -- file name to use
  811. **    char    *av[6];        -- window name to dump
  812. **
  813. ** Returns:
  814. **
  815. **    short;                -- 1 if success, 0 if failure
  816. **
  817. */
  818.  
  819. short    VRfile(union arg av[], char *unused)
  820. {
  821. #ifdef IMPLEMENTED
  822.     #pragma unused (unused)
  823.     VRW    *w;
  824.  
  825.     /*    Look up the window */
  826.  
  827.     w = VRlookup(av[6].a_ptr);
  828.  
  829.     if (w == (VRW *)0L)
  830.         return 0;
  831.  
  832.     /*    call the low level file routine */
  833.  
  834.     return RRfile(w, av[0].a_num, av[1].a_num, av[2].a_num, av[3].a_num,
  835.         av[4].a_num, av[5].a_ptr);
  836. #else 
  837.     UNUSED_ARG(av)
  838.     UNUSED_ARG(unused)
  839.     return 0;
  840. #endif IMPLEMENTED
  841. }
  842.  
  843. /*
  844. ** VRclick    -- Click the Slide Camera -- very machine dependent
  845. **
  846. ** Arguments:
  847. **
  848. **    union arg    av[];        -- the argument vector
  849. **
  850. **    char    *av[0];            -- window name
  851. **
  852. ** Returns:
  853. **
  854. **    short;                    -- 1 if success, 0 if failure
  855. */
  856.  
  857. short    VRclick(union arg av[], char *unused)
  858. {
  859. #ifdef IMPLEMENTED
  860.     #pragma unused (unused)
  861.     VRW    *w;
  862.  
  863.     /*    look up the window */
  864.  
  865.     w = VRlookup(av[0].a_ptr);
  866.  
  867.     if (w == (VRW *)0L)
  868.         return 0;
  869.  
  870.     return RRclick(w);
  871. #else 
  872.     UNUSED_ARG(av)
  873.     UNUSED_ARG(unused)
  874.     return 0;
  875. #endif IMPLEMENTED
  876. }
  877.  
  878. /*
  879. ** VRmsave    -- Save the named colormap to the file -- saves the whole thing
  880. **
  881. ** Arguments:
  882. **
  883. **    union arg    av[];        -- the argument vector
  884. **
  885. **    char    *av[0];            -- file name
  886. **    char    *av[1];            -- window name
  887. **
  888. ** Returns:
  889. **
  890. **    short;                    -- 1 if success, 0 if failure
  891. */
  892.  
  893. short    VRmsave(union arg av[], char *unused)
  894. {
  895. #ifdef IMPLEMENTED
  896.     #pragma unused (unused)
  897.     VRW    *w;
  898.  
  899.     /*    look up the window */
  900.     w = VRlookup(av[1].a_ptr);
  901.  
  902.     if (w == (VRW *)0L)
  903.         return 0;
  904.  
  905.     return RRmsave(w, av[0].a_ptr);
  906. #else 
  907.     UNUSED_ARG(av)
  908.     UNUSED_ARG(unused)
  909.     return 0;
  910. #endif IMPLEMENTED
  911. }
  912.  
  913. /*
  914. ** VRlookup            -- find an entry in the list by name
  915. **
  916. ** Arguments:
  917. **
  918. **    char    *name;    -- the name of the window
  919. **
  920. ** Returns:
  921. **
  922. **    VRW    *w;            -- pointer to window structure, (VRW *)0 if not found
  923. **
  924. */
  925.  
  926. VRW    *VRlookup(char *name)
  927. {
  928.     VRW    *w = VRhead.w_next;
  929.  
  930.     while (w) {
  931.         if (!strcmp(w->w_name, name) && !w->w_used) {    /* same name, not old dup */
  932.             if (w->w_rr.wn < 0)                            /* maybe window don't work */
  933.                 return(NULL);
  934.             MacRGsetwindow(w->w_rr.wn);
  935.             return(w);
  936.             }
  937.         w = w->w_next;
  938.     }
  939.  
  940.     return(NULL);
  941. }
  942.  
  943. /*
  944. ** VRcleanup -- remove all windows from the screen
  945. **
  946. ** Arguments:
  947. **
  948. **    None.
  949. **
  950. ** Returns:
  951. **
  952. **    short;    1    -- always successful, or there's nothing you can do
  953. **                -- about it anyways...
  954. **
  955. */
  956.  
  957. short    VRcleanup(void)
  958. {
  959.     VRW *w = VRhead.w_next;
  960.     VRW *x;
  961.  
  962.     while (w != (VRW *)0L) {
  963.         x = w->w_next;
  964.         MacRGremove( w->w_rr.wn);
  965.         w = x;
  966.     }
  967.  
  968.     return 1;
  969. }
  970.  
  971. /************************************************************************/
  972. /*  decoding
  973. *   handle the special ASCII printable character encoding of data bytes.
  974. */
  975.  
  976. /***********************************************************************/
  977. /*
  978. *  123 precedes #'s 0-63 
  979. *  124 precedes #'s 64-127
  980. *  125 precedes #'s 128-191
  981. *  126 precedes #'s 192-255
  982. *  overall:  realchar = (specialchar - 123)*64 + (char-32) 
  983. *            specialchar = r div 64 + 123
  984. *            char = r mod 64 + 32
  985. */
  986. /***********************************************************************/
  987. static short dstate=FRSKIP,dspec=0;
  988.  
  989. /*    set up receive */
  990. void    decode0(void)
  991. {
  992.     dstate = FRIN;
  993. }
  994.  
  995. short    decode1(char c)
  996. {
  997.     switch (dstate) {
  998.         case FRSKIP:
  999.             return(-1);
  1000.     
  1001.         case FRIN:                        /* decoding */
  1002.             if (c > 31 && c < 123)
  1003.                 return(c);
  1004.             else {
  1005.                 dspec = c;                /* save special character */
  1006.                 dstate = FRSPECIAL;        /* doing special character */
  1007.             }
  1008.             return(-1);
  1009.             
  1010.         case FRSPECIAL:
  1011.             switch (dspec) {
  1012.                 case 123:
  1013.                 case 124:
  1014.                 case 125:
  1015.                 case 126:            /* encoded character */
  1016.                     dstate = FRIN;
  1017.                     return(((dspec - 123)<< 6) - 32 + c);
  1018.                     
  1019.                 default:            /* mistaken character in stream */
  1020.                     dstate = FRIN;  /* assume not special */
  1021.                     return(decode1(c));  /* check for sure */
  1022.                     break;
  1023.                 }
  1024.         break;
  1025.     } // switch (dstate)
  1026. }
  1027.